package com.cj.service.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.cj.mapper.UserMapper;
import com.cj.pojo.PageBean;
import com.cj.pojo.User;
import com.cj.service.UserService;
import com.cj.pojo.dto.UserUpdateDTO;
import com.cj.pojo.dto.UserUpdateRequestDTO;
import com.cj.utils.Md5Util;
import com.cj.utils.ThreadLocalUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

import com.cj.exception.BaseException;
import com.cj.exception.ErrorCode;
import com.cj.service.RedisCacheService;
import com.cj.pojo.UserStatus;

@Service
public class UserServiceImpl implements UserService {
    private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
    
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private RedisCacheService redisCacheService;

    @Override
    public User login(String username, String password) {
        logger.info("尝试登录用户: {}", username);
        
        try {
            // 查询用户
            User user = userMapper.findByUserName(username);
            if (user == null) {
                String errorMsg = String.format("用户[%s]不存在", username);
                logger.warn(errorMsg);
                throw new BaseException(ErrorCode.USER_NOT_FOUND, errorMsg);
            }
        
            // 验证密码
            String encryptedPassword = Md5Util.getMD5String(password);
            logger.debug("用户[{}]输入密码MD5: {}, 数据库存储密码MD5: {}", 
                username, encryptedPassword, user.getPassword());
                
            if (!user.getPassword().equals(encryptedPassword)) {
                String errorMsg = String.format("用户[%s]密码不匹配", username);
                logger.warn(errorMsg);
                throw new BaseException(ErrorCode.AUTH_ERROR, errorMsg);
            }
            
            // 检查用户状态
            if (user.getStatus() == UserStatus.DISABLED) {
                String errorMsg = "用户已被禁用，请联系管理员";
                logger.warn("尝试登录已禁用用户: {}, 错误信息: {}", username, errorMsg);
                throw new BaseException(ErrorCode.AUTH_FORBIDDEN, errorMsg);
            }
            
            logger.info("用户登录成功: {}", username);
            return user;
        } catch (org.mybatis.spring.MyBatisSystemException e) {
            String rootCause = e.getRootCause() != null ? e.getRootCause().getMessage() : "未知数据库错误";
            String errorMsg = "系统繁忙，请稍后再试";
            logger.error("用户[{}]登录失败 - 数据库异常: {}", username, rootCause, e);
            throw new BaseException(ErrorCode.DATABASE_ERROR, errorMsg);
        } catch (BaseException e) {
            logger.error("用户[{}]登录失败 - 业务异常: {}", username, e.getMessage(), e);
            throw e;
        } catch (Exception e) {
            String errorMsg = "系统繁忙，请稍后再试";
            logger.error("用户[{}]登录失败 - 系统异常: {}", username, e.getMessage(), e);
            throw new BaseException(ErrorCode.SYSTEM_ERROR, errorMsg);
        }
    }
    @Override
    public User findByUserName(String username) {
        // 先尝试从缓存获取
        User user = userMapper.findByUserName(username);
        if (user != null) {
            redisCacheService.cacheUserInfo(Long.valueOf(user.getId()), user);
            return user;
        }
        // 从数据库获取
        user = userMapper.findByUserName(username);
        if (user != null) {
            redisCacheService.cacheUserInfo(Long.valueOf(user.getId()), user);
        }
        return user;
    }

    @Override
    public void register(String username, String password) {
        try {
            logger.info("开始注册用户: {}", username);
            
            // 检查用户名是否已存在
            User existingUser = userMapper.findByUserName(username);
            if (existingUser != null) {
                String errorMsg = String.format("用户名[%s]已存在", username);
                logger.warn(errorMsg);
                throw new BaseException(ErrorCode.USER_EXISTS, errorMsg);
            }
            
            // 加密密码
            String md5String = Md5Util.getMD5String(password);
            logger.debug("用户[{}]密码加密完成", username);
            
            // 添加用户
            int result = userMapper.add(username, md5String);
            if (result <= 0) {
                String errorMsg = String.format("用户[%s]注册失败，数据库操作未生效", username);
                logger.error(errorMsg);
                throw new BaseException(ErrorCode.SYSTEM_ERROR, errorMsg);
            }
            
            logger.info("用户[{}]注册成功", username);
        } catch (BaseException e) {
            logger.error("用户[{}]注册失败 - 业务异常: {}", username, e.getMessage(), e);
            throw e;
        } catch (Exception e) {
            String errorMsg = String.format("用户[%s]注册失败 - 系统异常", username);
            logger.error(errorMsg, e);
            new BaseException(ErrorCode.SYSTEM_ERROR, errorMsg);
        }
    }

    @Override
    public void update(User user) {
        user.setUpdateTime(LocalDateTime.now());
        userMapper.update(user);
        // 更新缓存
        redisCacheService.cacheUserInfo(Long.valueOf(user.getId()), user);
    }

    @Override
    @Transactional
    public void updateUserInfo(Long userId, UserUpdateDTO userUpdateDTO) {
        User user = userMapper.findById(userId);
        if (user == null) {
            throw new BaseException(ErrorCode.USER_NOT_FOUND, "用户不存在");
        }
        
        // 只更新允许修改的字段
        if (userUpdateDTO.getNickname() != null) {
            user.setNickname(userUpdateDTO.getNickname());
        }
        if (userUpdateDTO.getEmail() != null) {
            user.setEmail(userUpdateDTO.getEmail());
        }
        if (userUpdateDTO.getUserPic() != null) {
            user.setUserPic(userUpdateDTO.getUserPic());
        }
        
        user.setUpdateTime(LocalDateTime.now());
        userMapper.update(user);
        redisCacheService.cacheUserInfo(userId, user);
    }

    @Override
    public void updateAvatar(String avatarUrl) {
        Map<String,Object> map = ThreadLocalUtil.get();
        Integer id = (Integer) map.get("id");
        userMapper.updateAvatar(avatarUrl,id);
    }

    @Override
    public void updatePwd(String newPwd) {
        Map<String,Object> map = ThreadLocalUtil.get();
        Integer id = (Integer) map.get("id");
        userMapper.updatePwd(Md5Util.getMD5String(newPwd),id);
    }

    @Override
    public PageBean<User> listUsers(Integer pageNum, Integer pageSize, UserStatus status, String role) {
        PageHelper.startPage(pageNum, pageSize);
        List<User> users = userMapper.listUsers(status, role);
        Page<User> p = (Page<User>) users;
        return new PageBean<>(p.getTotal(), p.getResult());
    }

    @Override
    @Transactional
    public void updateStatus(Long id, UserStatus status) {
        userMapper.updateStatus(id, status);
        // 使缓存失效
        redisCacheService.deleteCache("user:" + id);
    }

    @Override
    @Transactional
    public void updateRole(Long id, String role) {
        userMapper.updateRole(id, role);
        // 使缓存失效
        redisCacheService.deleteCache("user:" + id);
    }

    @Override
    @Transactional
    public void deleteUser(Long id) {
        logger.info("尝试删除用户ID: {}", id);
        
        // 检查用户是否存在
        User user = userMapper.findById(id);
        if (user == null) {
            String errorMsg = String.format("用户ID[%s]不存在", id);
            logger.warn(errorMsg);
            throw new BaseException(ErrorCode.USER_NOT_FOUND, errorMsg);
        }

        // 检查是否有关联文章
        int articleCount = userMapper.countArticlesByUserId(id);
        if (articleCount > 0) {
            String errorMsg = String.format("用户ID[%s]有关联文章，不能删除", id);
            logger.warn(errorMsg);
            throw new BaseException(ErrorCode.USER_HAS_RELATED_DATA, errorMsg);
        }

        // 检查是否有关联分类
        int categoryCount = userMapper.countCategoriesByUserId(id);
        if (categoryCount > 0) {
            String errorMsg = String.format("用户ID[%s]有关联分类，不能删除", id);
            logger.warn(errorMsg);
            throw new BaseException(ErrorCode.USER_HAS_RELATED_DATA, errorMsg);
        }

        // 检查是否有评论
        int commentCount = userMapper.countCommentsByUserId(id);
        if (commentCount > 0) {
            String errorMsg = String.format("用户ID[%s]有关联评论，不能删除", id);
            logger.warn(errorMsg);
            throw new BaseException(ErrorCode.USER_HAS_RELATED_DATA, errorMsg);
        }

        // 执行删除
        int result = userMapper.deleteById(id);
        if (result <= 0) {
            String errorMsg = String.format("删除用户ID[%s]失败", id);
            logger.error(errorMsg);
            throw new BaseException(ErrorCode.SYSTEM_ERROR, errorMsg);
        }

        // 清理缓存
        redisCacheService.deleteCache("user:" + id);
        logger.info("成功删除用户ID: {}", id);
    }
    @Override
    @Transactional
    public void updateUserInfo(Integer userId, UserUpdateRequestDTO updateDTO) {
        User user = userMapper.findById(userId.longValue());
        if (user == null) {
            throw new BaseException(ErrorCode.USER_NOT_FOUND);
        }
        
        if (updateDTO.getNickname() != null) {
            user.setNickname(updateDTO.getNickname());
        }
        if (updateDTO.getEmail() != null) {
            user.setEmail(updateDTO.getEmail());
        }
        if (updateDTO.getUserPic() != null) {
            user.setUserPic(updateDTO.getUserPic());
        }
        
        user.setUpdateTime(LocalDateTime.now());
        userMapper.update(user);
        redisCacheService.cacheUserInfo(userId.longValue(), user);
    }
}
